﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Elderos.Highlight.Search;
using Elderos.Ontology;

namespace Elderos.Highlight.Rules
{
    [RankingRule("SureSynonym", RuleType.Misc)]
    public class RuleSureSynonym : RankingRule
    {
        public RuleSureSynonym(IOntologyData ontology) : base(ontology)
        {}

#pragma warning disable 1998
        protected async override Task<Dictionary<TextEntity, IRuleResult>> InnerRank(HighlightResult highlightResult)
#pragma warning restore 1998
        {
            var ruleResults = new Dictionary<TextEntity, IRuleResult>();
            Dictionary<int, List<Position>> singleEntities = GetSingleEntities(highlightResult);

            foreach (var position in highlightResult.Positions.SelectMany(x => x.SubpositionsFlattened))
            {
                foreach (var textEntity in position.Entities)
                {
                    List<Position> singleInfos;
                    if (singleEntities.TryGetValue(textEntity.EntityID, out singleInfos))
                    {
                        ruleResults.Add(textEntity, new BinomialResult(Name, GetCoef(singleInfos)));
                    }
                }
            }

            return ruleResults;
        }

        private static Dictionary<int, List<Position>> GetSingleEntities(HighlightResult highlightResult)
        {
            var singleEntities = new Dictionary<int, List<Position>>();

            foreach (var position in highlightResult.Positions.SelectMany(x => x.SubpositionsFlattened))
            {
                if (position.Entities.Count > 1) continue;

                int entityID = position.Entities[0].EntityID;

                if (singleEntities.ContainsKey(entityID))
                {
                    singleEntities[entityID].Add(position);
                }
                else
                {
                    singleEntities.Add(entityID, new List<Position>() {position});
                }
            }
            return singleEntities;
        }

        private bool GetCoef(IEnumerable<Position> singleInfos)
        {
            return singleInfos.Any(x => !Ontology.CommonWords.Contains(x.Text));
        }

        public override IRuleResult EmptyResult
        {
            get { return new BinomialResult(Name, false); }
        }
    }
}
